package org.nalai.tools;


import com.jcraft.jsch.*;

import java.io.*;
import java.util.Vector;

public class ShellUtils {

    private static Session session;


    /**
     * 连接到指定的IP
     *
     * @param user   用户名
     * @param passwd 密码
     * @param host   设备IP
     * @throws Exception
     */
    private static void connect(String user, String passwd, String host) throws Exception {

        JSch jsch = new JSch();
        session = jsch.getSession(user, host, 22);
        session.setPassword(passwd);

        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
    }

    /**
     * 执行相关的命令
     *
     * @param host    目标机器IP
     * @param user    用户名
     * @param passwd  密码
     * @param command 要执行的命令
     * @return 执行结果
     * @throws Exception
     */
    public static String execCmd(String host, String user, String passwd, String command) throws Exception {

        connect(user, passwd, host);

        BufferedReader reader = null;
        Channel channel = null;

        try {
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);

            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);

            channel.connect();
            InputStream in = channel.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder buf = new StringBuilder();
            String line;
            while (null != (line = reader.readLine())) {
                buf.append(line).append("\n");
            }
            return buf.toString();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            try {
                assert reader != null;
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            channel.disconnect();
            session.disconnect();
        }

        return "";
    }

    /**
     * 利用JSch包实现SFTP下载、上传文件
     *
     * @param ip     主机IP
     * @param user   主机登陆用户名
     * @param psw    主机登陆密码
     * @param port   主机ssh2登陆端口，如果取默认值，传-1
     * @param srcDir 源文件所在的目录
     * @param src    源文件
     * @param dst    目的文件
     * @throws Exception
     */
    public static void sftpDownload(String ip, String user, String psw, int port, String srcDir, String src, String dst) throws Exception {

        Session session;
        Channel channel = null;


        JSch jsch = new JSch();

        if (port <= 0) {
            //连接服务器，采用默认端口
            session = jsch.getSession(user, ip);
        } else {
            //采用指定的端口连接服务器
            session = jsch.getSession(user, ip, port);
        }

        //如果服务器连接不上，则抛出异常
        if (session == null) {
            throw new Exception("session is null");
        }

        //设置登陆主机的密码
        session.setPassword(psw);//设置密码
        //设置第一次登陆的时候提示，可选值：(ask | yes | no)
        session.setConfig("StrictHostKeyChecking", "no");
        //设置登陆超时时间
        session.connect(30000);

        try {
            //创建sftp通信通道
            channel = session.openChannel("sftp");
            channel.connect(1000);
            ChannelSftp sftp = (ChannelSftp) channel;


            //进入服务器指定的文件夹，比如 /root
            sftp.cd(srcDir);

            //列出服务器指定的文件列表
            Vector v = sftp.ls("*.txt");
            for (Object aV : v) {
                System.out.println(aV);
            }

            //以下代码实现从本地上传一个文件到服务器，如果要实现下载，对换以下流就可以了
//            OutputStream outstream = sftp.put("1.txt");
            //  InputStream instream = new FileInputStream(new File("e:/print.txt"));

            InputStream instream = sftp.get(src);
            OutputStream outstream = new FileOutputStream(new File(dst));

            byte b[] = new byte[1024];
            int n;
            while ((n = instream.read(b)) != -1) {
                outstream.write(b, 0, n);
            }

            outstream.flush();
            outstream.close();
            instream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.disconnect();
            if (null != channel) {
                channel.disconnect();
            }
        }
    }
}
